<template>
	<div>
		<el-drawer
			v-bind="$attrs"
			v-on="$listeners"
			@opened="onOpen"
			@close="onClose"
		>
			<div class="action-bar" :style="{ 'text-align': 'left' }">
				<span class="bar-btn" @click="refresh">
					<i class="el-icon-refresh" />
					刷新
				</span>
				<span ref="copyBtn" class="bar-btn copy-json-btn">
					<i class="el-icon-document-copy" />
					复制JSON
				</span>
				<span class="bar-btn" @click="exportJsonFile">
					<i class="el-icon-download" />
					导出JSON文件
				</span>
				<span
					class="bar-btn delete-btn"
					@click="$emit('update:visible', false)"
				>
					<i class="el-icon-circle-close" />
					关闭
				</span>
			</div>
			<div id="editorJson" class="json-editor" />
		</el-drawer>
	</div>
</template>

<script>
import { beautifierConf } from '@/utils/index'
import ClipboardJS from 'clipboard'
import { saveAs } from 'file-saver'
import loadMonaco from '@/utils/loadMonaco'
import loadBeautifier from '@/utils/loadBeautifier'

let beautifier
let monaco

export default {
	components: {},
	props: {
		jsonStr: {
			type: String,
			required: true,
		},
	},
	data() {
		return {}
	},
	computed: {},
	watch: {},
	created() {},
	mounted() {
		window.addEventListener('keydown', this.preventDefaultSave)
		const clipboard = new ClipboardJS('.copy-json-btn', {
			text: () => {
				this.$notify({
					title: '成功',
					message: '代码已复制到剪切板，可粘贴。',
					type: 'success',
				})
				return this.beautifierJson
			},
		})
		clipboard.on('error', () => {
			this.$message.error('代码复制失败')
		})
	},
	beforeDestroy() {
		window.removeEventListener('keydown', this.preventDefaultSave)
	},
	methods: {
		preventDefaultSave(e) {
			if (e.key === 's' && (e.metaKey || e.ctrlKey)) {
				e.preventDefault()
			}
		},
		onOpen() {
			loadBeautifier(btf => {
				beautifier = btf
				this.beautifierJson = beautifier.js(this.jsonStr, beautifierConf.js)

				loadMonaco(val => {
					monaco = val
					this.setEditorValue('editorJson', this.beautifierJson)
				})
			})
		},
		onClose() {},
		setEditorValue(id, codeStr) {
			if (this.jsonEditor) {
				this.jsonEditor.setValue(codeStr)
			} else {
				this.jsonEditor = monaco.editor.create(document.getElementById(id), {
					value: codeStr,
					theme: 'vs-dark',
					language: 'json',
					automaticLayout: true,
				})
				// ctrl + s 刷新
				this.jsonEditor.onKeyDown(e => {
					if (e.keyCode === 49 && (e.metaKey || e.ctrlKey)) {
						this.refresh()
					}
				})
			}
		},
		exportJsonFile() {
			this.$prompt('文件名:', '导出文件', {
				inputValue: `${+new Date()}.json`,
				closeOnClickModal: false,
				inputPlaceholder: '请输入文件名',
			}).then(({ value }) => {
				if (!value) value = `${+new Date()}.json`
				const codeStr = this.jsonEditor.getValue()
				const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
				saveAs(blob, value)
			})
		},
		refresh() {
			try {
				this.$emit('refresh', JSON.parse(this.jsonEditor.getValue()))
			} catch (error) {
				this.$notify({
					title: '错误',
					message: 'JSON格式错误，请检查',
					type: 'error',
				})
			}
		},
	},
}
</script>

<style lang="scss" scoped>
@import './styles/mixin.scss';

::v-deep .el-drawer__header {
	display: none;
}
@include action-bar;

.json-editor {
	height: calc(100vh - 33px);
}
</style>
